package com.security;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.UserEntity;
import com.entity.YonghuEntity;
import com.service.UserService;
import com.service.YonghuService;
import com.utils.ResultCode;
import com.exceptions.MyAuthenticationException;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

/**
 * @author t-zhaoheng
 * @since 2022/3/28 用户只有在发送post格式的 /login 请求时，才会走到 UsernamePasswordAuthenticationFilter 中来
 */
@Slf4j
public class MyUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

  @Resource
  UserService userService;

  @Resource
  YonghuService yonghuService;

  BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

  protected MyUsernamePasswordAuthenticationFilter() {
    super(new AntPathRequestMatcher("/**/login"));
  }

  @SneakyThrows
  @Override
  public Authentication attemptAuthentication(HttpServletRequest request,
      HttpServletResponse response) throws AuthenticationException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    if (StrUtil.isEmpty(username) || StrUtil.isEmpty(password)) {
      // 这里抛出异常的话，程序就会直接走 failureHandler 里面
      throw new MyAuthenticationException(ResultCode.PARAM_NOT_COMPLETE.message());
    }

    // 验证密码
    String requestURI = request.getRequestURI();
    if(requestURI.contains("yonghu")) {
      if(!yonghuService.yonghuExist(username)) {
        throw new MyAuthenticationException(ResultCode.USER_ACCOUNT_NOT_EXIST.message());
      }
      if(!yonghuService.checkPassword(username, password)) {
        throw new MyAuthenticationException(ResultCode.USER_CREDENTIALS_ERROR.message());
      }
    }
    if(requestURI.contains("user")) {
      if(!userService.userExist(username)) {
        throw new MyAuthenticationException(ResultCode.USER_ACCOUNT_NOT_EXIST.message());
      }
      if(!userService.checkPassword(username, password)) {
        throw new MyAuthenticationException(ResultCode.USER_CREDENTIALS_ERROR.message());
      }
    }

    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
        username, password);
//      this.setDetails(request, authenticationToken);
    authenticationToken.setDetails(authenticationDetailsSource.buildDetails(request));
    // 前往 UserDetailsService ，验证登录信息，如果AuthenticationManager中配置了的话
    // 这里要return出去，不然无法走到 success or failure handler 中
    return this.getAuthenticationManager().authenticate(authenticationToken);
  }
}
